package com.example.cm_base

import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType

/**
 * 具有ViewModel和ViewBinding支持的基础Activity
 * 通过反射自动创建对应的ViewModel和ViewBinding实例
 *
 * 使用方法：
 * 1. 继承此BaseActivity
 * 2. 指定泛型参数VB (ViewBinding) 和 VM (ViewModel)
 * 3. 重写onActivityCreated方法处理视图逻辑
 */
abstract class BaseActivity<VB : ViewBinding, VM : ViewModel> : AppCompatActivity() {

    // ViewBinding延迟初始化属性，非空
    protected lateinit var binding: VB
        private set

    // ViewModel实例
    protected lateinit var viewModel: VM
        private set

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = initViewBinding()
        setContentView(binding.root)

        viewModel = initViewModel()
        initObservers()
        onActivityCreated(savedInstanceState)
    }

    /**
     * 使用反射创建ViewBinding实例
     */
    @Suppress("UNCHECKED_CAST")
    private fun initViewBinding(): VB {
        try {
            val type = (javaClass.genericSuperclass as ParameterizedType)
                .actualTypeArguments[0] as Class<VB>

            val inflateMethod = type.getDeclaredMethod(
                "inflate",
                LayoutInflater::class.java
            )
            return inflateMethod.invoke(null, layoutInflater) as VB
        } catch (e: Exception) {
            throw RuntimeException("ViewBinding初始化失败", e)
        }
    }

    /**
     * 使用ViewModelProvider创建ViewModel实例
     */
    @Suppress("UNCHECKED_CAST")
    private fun initViewModel(): VM {
        try {
            val type = (javaClass.genericSuperclass as ParameterizedType)
                .actualTypeArguments[1] as Class<VM>
            return ViewModelProvider(this)[type]
        } catch (e: Exception) {
            throw RuntimeException("ViewModel初始化失败", e)
        }
    }

    /**
     * 子类可以重写此方法来设置数据观察者
     */
    protected open fun initObservers() {

    }

    /**
     * 子类必须实现此方法进行Activity创建后的初始化
     */
    protected abstract fun onActivityCreated(savedInstanceState: Bundle?)

}